﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace API.Models.Repository
{
    public class LOCATIONS_MAPPING_Repository : GenericRepository<PartnerDbContext, LOCATIONS_MAPPING>
    {
        /// <summary>
        /// Получить соответствие для заданной локации контрагента
        /// </summary>
        /// <param name="LOCATION_GUID">Идентификатор локации</param>
        /// <returns></returns>
        public LOCATION_MAP GetMapping(Guid LOCATION_GUID)
        {
            /// To do: сделать проверку на доступы
            var LEFT_LOCATION = _entities.WH_LOCATIONS
                .Include("COMPANY")
                .SingleOrDefault(r => r.GUID_RECORD == LOCATION_GUID);


            var sql = @"
            SELECT [{0}] GUID_RECORD
            FROM WH_LOCATIONS_MAPPING
            WHERE 1 = 1
                AND [{1}] = '{2}' 
                AND [{0}] IS NOT NULL";

            sql = String.Format(sql, this.session.COMPANY_GUID, LEFT_LOCATION.COMPANY_GUID, LOCATION_GUID);

            var data = this.Context.Database.SqlQuery<CommonDbClass>(sql).SingleOrDefault();

            if (data == null)
                return new LOCATION_MAP
                {
                    LEFT_LOCATION_MAP = LEFT_LOCATION
                };


            var RIGHT_LOCATION = _entities.WH_LOCATIONS
                .Include("COMPANY")
                .SingleOrDefault(r => r.GUID_RECORD == data.GUID_RECORD);

            return new LOCATION_MAP
                {
                    LEFT_LOCATION_MAP = LEFT_LOCATION,
                    RIGHT_LOCATION_MAP = RIGHT_LOCATION
                };
        }

        public void SetMapping(LOCATION_MAP map)
        {
            var LEFT_LOCATION = _entities.WH_LOCATIONS
                .SingleOrDefault(r => r.GUID_RECORD == map.LEFT_LOCATION_MAP.GUID_RECORD);

            var RIGHT_LOCATION = _entities.WH_LOCATIONS
                .SingleOrDefault(r => r.GUID_RECORD == map.RIGHT_LOCATION_MAP.GUID_RECORD);

            var COMPANIES = _entities.WH_COMPANIES
                .Where(r => !r.OWNER_GUID.HasValue)
                .ToList();

            var sql = @"
            DECLARE
	            @LEFT_LOCATION_GUID		uniqueidentifier,
	            @RIGHT_LOCATION_GUID	uniqueidentifier,
	            @LEFT_GUID_RECORD	uniqueidentifier,
	            @RIGHT_GUID_RECORD	uniqueidentifier;

            SET @LEFT_LOCATION_GUID = '{0}';
            SET @RIGHT_LOCATION_GUID = '{1}';

            SELECT
	            @LEFT_GUID_RECORD = GUID_RECORD
            FROM 
	            WH_LOCATIONS_MAPPING
            WHERE 
	            [{2}] = @LEFT_LOCATION_GUID;

            SELECT
	            @RIGHT_GUID_RECORD = GUID_RECORD
            FROM 
	            WH_LOCATIONS_MAPPING
            WHERE 
	            [{3}] = @RIGHT_LOCATION_GUID;

            IF @LEFT_GUID_RECORD = @RIGHT_GUID_RECORD BEGIN
	            -- Ничего не делаем
	            RETURN;
            END;

            IF @LEFT_GUID_RECORD IS NULL AND @RIGHT_GUID_RECORD IS NULL BEGIN

	            INSERT INTO WH_LOCATIONS_MAPPING ([{2}], [{3}])
	            VALUES (@LEFT_LOCATION_GUID, @RIGHT_LOCATION_GUID);

	            SELECT 'INSERT NEW RECORD';
	            RETURN;
            END;

            IF @LEFT_GUID_RECORD IS NOT NULL AND @RIGHT_GUID_RECORD IS NOT NULL BEGIN

	            UPDATE WH_LOCATIONS_MAPPING SET
		            {4}
	            WHERE
		            GUID_RECORD = @LEFT_GUID_RECORD;
	
	            DELETE WH_LOCATIONS_MAPPING	WHERE
		            GUID_RECORD = @RIGHT_GUID_RECORD;

	            SELECT 'UPDATE RECORD AND DELETE';
	            RETURN;
            END;

            IF @LEFT_GUID_RECORD IS NOT NULL AND @RIGHT_GUID_RECORD IS NULL BEGIN
	
	            UPDATE WH_LOCATIONS_MAPPING SET
		            [{3}] = @RIGHT_LOCATION_GUID
	            WHERE
		            GUID_RECORD = @LEFT_GUID_RECORD;

	            RETURN;
            END;

            IF @LEFT_GUID_RECORD IS NULL AND @RIGHT_GUID_RECORD IS NOT NULL BEGIN

	            UPDATE WH_LOCATIONS_MAPPING SET
		            [{2}] = @LEFT_LOCATION_GUID
	            WHERE
		            GUID_RECORD = @RIGHT_GUID_RECORD;

	            RETURN;
            END;";

            sql = String.Format(sql,
                LEFT_LOCATION.GUID_RECORD, RIGHT_LOCATION.GUID_RECORD,
                LEFT_LOCATION.COMPANY_GUID, RIGHT_LOCATION.COMPANY_GUID,
                String.Join(", ", COMPANIES.Select(r => String.Format(
                    "[{0}] = ISNULL([{0}], (SELECT [{0}] FROM WH_LOCATIONS_MAPPING WHERE GUID_RECORD = @RIGHT_GUID_RECORD))",
                    r.GUID_RECORD.ToString()))));

            this.Context.Database.ExecuteSqlCommand(sql);

            /// Перекодировка связанных с товаром документов
            var outgoing_invoices_repository = new OutgoingInvoices_Repository();
            var incoming_invoices_repository = new IncomingInvoices_Repository();

            var outgoing_invoices = outgoing_invoices_repository
                .Find(r => r.LOCATION_GUID == LEFT_LOCATION.GUID_RECORD || r.LOCATION_GUID == RIGHT_LOCATION.GUID_RECORD)
                .ToList();

            var incoming_invoices = incoming_invoices_repository
                .Find(r => r.LOCATION_GUID == LEFT_LOCATION.GUID_RECORD || r.LOCATION_GUID == RIGHT_LOCATION.GUID_RECORD)
                .ToList();

            foreach (var r in outgoing_invoices)
                outgoing_invoices_repository.Recode(r.GUID_RECORD);

            foreach (var r in incoming_invoices)
                outgoing_invoices_repository.Recode(r.GUID_RECORD);
        }

    }
}